package pl.un4giv3n.mightvsmagic.admin.action;

import java.util.Iterator;
import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.Query;

import pl.un4giv3n.mightvsmagic.action.PersistenceAction;
import pl.un4giv3n.mightvsmagic.entity.ActivityType;
import pl.un4giv3n.mightvsmagic.entity.SpecialSkill;
import pl.un4giv3n.mightvsmagic.entity.SpecialSkillTemplate;
import pl.un4giv3n.mightvsmagic.entity.User;
import pl.un4giv3n.mightvsmagic.entity.UserActivity;
import pl.un4giv3n.mightvsmagic.entity.UserType;
import pl.un4giv3n.mightvsmagic.utils.ActivityLogUtil;

/**
 * @author andrzejewskia
 * this action adds new items to the bazar
 * this action should be performed by admin ONLY
 */
public class EditSkillAction extends PersistenceAction {

	private static final long serialVersionUID = 1L;
	
	private Long skillId;
	/**
	 * session user
	 */
	private User user;
	/**
	 * weapon name
	 */
	private String name;
	/**
	 * item price
	 */
	private int price;
	/**
	 * item premium price
	 */
	private int premiumPrice;
	/**
	 * item strenght modifier
	 */
	private int strengthMod;
	/**
	 * item stamina modifier
	 */
	private int staminaMod;
	/**
	 * item mana modifier
	 */
	private int manaMod;
	/**
	 * item attack modifier
	 */
	private int attackMod;
	/**
	 * item parry modifier
	 */
	private int defenceMod;
	private int speedMod;
	/**
	 * item strenght Req
	 */
	private int strengthReq;
	/**
	 * item stamina Req
	 */
	private int staminaReq;
	/**
	 * item mana Req
	 */
	private int manaReq;
	/**
	 * item attack Req
	 */
	private int attackReq;
	/**
	 * item parry Req
	 */
	private int defenceReq;
	
	private long requiredFightExp;
	private long requiredMagicExp;
	
	private double dmgFactor;
	private double defFactor;
	private double speedFactor;
	private int minDmgIncrease;
	private int maxDmgIncrease;
	private int minDefIncrease;
	private int maxDefIncrease;
	private int iceDamage;
	private int fireDamage;
	private int earthDamage;
	private int windDamage;
	private int iceDefence;
	private int fireDefence;
	private int earthDefence;
	private int windDefence;
	private long[] requiresToLearn;
	private long[] blocksLearning;

	/* (non-Javadoc)
	 * @see pl.un4giv3n.mightvsmagic.action.PersistenceAction#execute()
	 */
	@Override
	public String execute() {
		EntityManager entityManager = getEntityManager();
		user = getSessionUser(entityManager);
		if (user == null || user.getUserType() != UserType.ADMIN) {
			addActionError("Zaloguj się");
			entityManager.close();
			return LOGIN;
		}
		entityManager.getTransaction().begin();
		SpecialSkillTemplate template;
		if(skillId != null){
			template = entityManager.find(SpecialSkillTemplate.class, skillId);
			updateTemplate(template);
			entityManager.merge(template);
			updateTemplateSkills(entityManager, template);
			UserActivity activity = ActivityLogUtil.createActivity(ActivityType.ADMIN_EDITSKILL, user.getId(), "Edycja skilla: " + template.toString());
			entityManager.persist(activity);
		}else{
			template = new SpecialSkillTemplate();
			updateTemplate(template);
			entityManager.persist(template);
		}
		entityManager.flush();
		entityManager.getTransaction().commit();
		entityManager.close();
		return SUCCESS;
	}

	private void updateTemplateSkills(EntityManager entityManager,
			SpecialSkillTemplate template) {
		Query query = entityManager.createNamedQuery("find.template.skills");
		query.setParameter("templateId", template.getId());
		@SuppressWarnings("unchecked")
		List<SpecialSkill> skills = query.getResultList();
		for (Iterator<SpecialSkill> iterator = skills.iterator(); iterator.hasNext();) {
			SpecialSkill specialSkill = iterator.next();
			updateSkill(specialSkill);
			entityManager.merge(specialSkill);
			
		}
	}

	private void updateSkill(SpecialSkill specialSkill) {
		specialSkill.setName(name);
		specialSkill.setStrenghtModifier(strengthMod);
		specialSkill.setStaminaModifier(staminaMod);
		specialSkill.setManaModifier(manaMod);
		specialSkill.setAttackModifier(attackMod);
		specialSkill.setParryModifier(defenceMod);
		specialSkill.setDefFactor(defFactor);
		specialSkill.setDmgFactor(dmgFactor);
		specialSkill.setMinDefIncrease(minDefIncrease);
		specialSkill.setMaxDefIncrease(maxDefIncrease);
		specialSkill.setMinDmgIncrease(minDmgIncrease);
		specialSkill.setMaxDmgIncrease(maxDmgIncrease);
		specialSkill.setFireDamage(fireDamage);
		specialSkill.setFireDefence(fireDefence);
		specialSkill.setIceDamage(iceDamage);
		specialSkill.setIceDefence(iceDefence);
		specialSkill.setEarthDamage(earthDamage);
		specialSkill.setEarthDefence(earthDefence);
		specialSkill.setWindDamage(windDamage);
		specialSkill.setWindDefence(windDefence);
		specialSkill.setPrice(price);
		specialSkill.setRequiresToLearn(requiresToLearn);
		specialSkill.setBlocksLearning(blocksLearning);
	}

	private SpecialSkillTemplate updateTemplate(SpecialSkillTemplate template) {
		template.setName(name);
		template.setRequiredFightExp(requiredFightExp);
		template.setRequiredMagicExp(requiredMagicExp);
		template.setStrenghtModifier(strengthMod);
		template.setStaminaModifier(staminaMod);
		template.setManaModifier(manaMod);
		template.setAttackModifier(attackMod);
		template.setParryModifier(defenceMod);
		template.setSpeedModifier(speedMod);
		template.setStrenghtReq(strengthReq);
		template.setStaminaReq(staminaReq);
		template.setManaReq(manaReq);
		template.setAttackReq(attackReq);
		template.setParryReq(defenceReq);
		template.setDefFactor(defFactor);
		template.setDmgFactor(dmgFactor);
		template.setSpeedFactor(speedFactor);
		template.setMinDefIncrease(minDefIncrease);
		template.setMaxDefIncrease(maxDefIncrease);
		template.setMinDmgIncrease(minDmgIncrease);
		template.setMaxDmgIncrease(maxDmgIncrease);
		template.setFireDamage(fireDamage);
		template.setFireDefence(fireDefence);
		template.setIceDamage(iceDamage);
		template.setIceDefence(iceDefence);
		template.setEarthDamage(earthDamage);
		template.setEarthDefence(earthDefence);
		template.setWindDamage(windDamage);
		template.setWindDefence(windDefence);
		template.setPrice(price);
		template.setPremiumPrice(premiumPrice);
		template.setRequiresToLearn(requiresToLearn);
		template.setBlocksLearning(blocksLearning);
		return template;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public int getPrice() {
		return price;
	}

	public void setPrice(int price) {
		this.price = price;
	}

	public int getStrengthMod() {
		return strengthMod;
	}

	public void setStrengthMod(int strengthMod) {
		this.strengthMod = strengthMod;
	}

	public int getStaminaMod() {
		return staminaMod;
	}

	public void setStaminaMod(int staminaMod) {
		this.staminaMod = staminaMod;
	}

	public int getManaMod() {
		return manaMod;
	}

	public void setManaMod(int manaMod) {
		this.manaMod = manaMod;
	}

	public int getAttackMod() {
		return attackMod;
	}

	public void setAttackMod(int attackMod) {
		this.attackMod = attackMod;
	}

	public int getDefenceMod() {
		return defenceMod;
	}

	public void setDefenceMod(int defenceMod) {
		this.defenceMod = defenceMod;
	}

	public int getStrengthReq() {
		return strengthReq;
	}

	public void setStrengthReq(int strengthReq) {
		this.strengthReq = strengthReq;
	}

	public int getStaminaReq() {
		return staminaReq;
	}

	public void setStaminaReq(int staminaReq) {
		this.staminaReq = staminaReq;
	}

	public int getManaReq() {
		return manaReq;
	}

	public void setManaReq(int manaReq) {
		this.manaReq = manaReq;
	}

	public int getAttackReq() {
		return attackReq;
	}

	public void setAttackReq(int attackReq) {
		this.attackReq = attackReq;
	}

	public int getDefenceReq() {
		return defenceReq;
	}

	public void setDefenceReq(int defenceReq) {
		this.defenceReq = defenceReq;
	}

	public long getRequiredFightExp() {
		return requiredFightExp;
	}

	public void setRequiredFightExp(long requiredFightExp) {
		this.requiredFightExp = requiredFightExp;
	}

	public long getRequiredMagicExp() {
		return requiredMagicExp;
	}

	public void setRequiredMagicExp(long requiredMagicExp) {
		this.requiredMagicExp = requiredMagicExp;
	}

	public Long getSkillId() {
		return skillId;
	}

	public void setSkillId(Long skillId) {
		this.skillId = skillId;
	}

	public User getUser() {
		return user;
	}

	public void setUser(User user) {
		this.user = user;
	}

	public double getDmgFactor() {
		return dmgFactor;
	}

	public void setDmgFactor(double dmgFactor) {
		this.dmgFactor = dmgFactor;
	}

	public double getDefFactor() {
		return defFactor;
	}

	public void setDefFactor(double defFactor) {
		this.defFactor = defFactor;
	}

	public int getMinDmgIncrease() {
		return minDmgIncrease;
	}

	public void setMinDmgIncrease(int minDmgIncrease) {
		this.minDmgIncrease = minDmgIncrease;
	}

	public int getMaxDmgIncrease() {
		return maxDmgIncrease;
	}

	public void setMaxDmgIncrease(int maxDmgIncrease) {
		this.maxDmgIncrease = maxDmgIncrease;
	}

	public int getMinDefIncrease() {
		return minDefIncrease;
	}

	public void setMinDefIncrease(int minDefIncrease) {
		this.minDefIncrease = minDefIncrease;
	}

	public int getMaxDefIncrease() {
		return maxDefIncrease;
	}

	public void setMaxDefIncrease(int maxDefIncrease) {
		this.maxDefIncrease = maxDefIncrease;
	}

	public int getIceDamage() {
		return iceDamage;
	}

	public void setIceDamage(int iceDamage) {
		this.iceDamage = iceDamage;
	}

	public int getFireDamage() {
		return fireDamage;
	}

	public void setFireDamage(int fireDamage) {
		this.fireDamage = fireDamage;
	}

	public int getEarthDamage() {
		return earthDamage;
	}

	public void setEarthDamage(int earthDamage) {
		this.earthDamage = earthDamage;
	}

	public int getWindDamage() {
		return windDamage;
	}

	public void setWindDamage(int windDamage) {
		this.windDamage = windDamage;
	}

	public int getFireDefence() {
		return fireDefence;
	}

	public void setFireDefence(int fireDefence) {
		this.fireDefence = fireDefence;
	}

	public int getEarthDefence() {
		return earthDefence;
	}

	public void setEarthDefence(int earthDefence) {
		this.earthDefence = earthDefence;
	}

	public int getWindDefence() {
		return windDefence;
	}

	public void setWindDefence(int windDefence) {
		this.windDefence = windDefence;
	}

	public int getIceDefence() {
		return iceDefence;
	}

	public void setIceDefence(int iceDefence) {
		this.iceDefence = iceDefence;
	}

	public String getRequiresToLearn() {
		StringBuilder sb = new StringBuilder();
		for (long requirement : requiresToLearn) {
			sb.append(requirement+",");
		}
		String reqs = sb.toString();
		return reqs.substring(0,reqs.lastIndexOf(","));
	}

	public void setRequiresToLearn(String requiresToLearn) {
		if(requiresToLearn == null || requiresToLearn.equals("")){
			this.requiresToLearn = null;
		}else{
			String[] reqs = requiresToLearn.split(",");
			this.requiresToLearn = new long[reqs.length];
			for (int i = 0; i < reqs.length; i++) {
				try{
					this.requiresToLearn[i] = Long.valueOf(reqs[i]);
				}catch (NumberFormatException e){
					//if someone messes something up, clear the requirements
					this.requiresToLearn = null;
					break;
				}
			}
		}
	}

	public int getPremiumPrice() {
		return premiumPrice;
	}

	public void setPremiumPrice(int premiumPrice) {
		this.premiumPrice = premiumPrice;
	}

	public long[] getBlocksLearning() {
		return blocksLearning;
	}

	public void setBlocksLearning(String blocksLearning) {
		if(blocksLearning == null || blocksLearning.equals("")){
			this.blocksLearning = null;
		}else{
			String[] blocks = blocksLearning.split(",");
			this.blocksLearning = new long[blocks.length];
			for (int i = 0; i < blocks.length; i++) {
				try{
					this.blocksLearning[i] = Long.valueOf(blocks[i]);
				}catch (NumberFormatException e){
					//if someone messes something up, clear the requirements
					this.blocksLearning = null;
					break;
				}
			}
		}
	}

	public int getSpeedMod() {
		return speedMod;
	}

	public void setSpeedMod(int speedMod) {
		this.speedMod = speedMod;
	}

	public double getSpeedFactor() {
		return speedFactor;
	}

	public void setSpeedFactor(double speedFactor) {
		this.speedFactor = speedFactor;
	}

}
